

local ustring = {};

local utf8_offset = utf8.offset;
local utf8_len = utf8.len;

function utf8_sub(s, i, j)
    local sl = utf8_len(s);
    i = i or 1;
    j = (not j or j > sl) and sl or j;
    
    if (i > sl or j < i) then return "" end 

    local ui = utf8.offset(s, i);
    local uj = utf8.offset(s, j + 1);
    return string.sub(s, ui, uj - 1);
end

function ustring:new(text)
    local us = setmetatable({}, {__index = ustring});

    us.text = tostring(text or "");

    return us;
end

function ustring:tostring()
    return self.text;
end

function ustring:len()
    return utf8_len(self.text);
end

function ustring:sub(i, j)
    return ustring:new(utf8_sub(self.text, i, j));
end

function ustring:insert(pos, text)
    text = tostring(text);
    self.text = utf8_sub(self.text, 1, pos - 1) .. text .. utf8_sub(self.text, pos);
end

function ustring:remove(pos, size)
    self.text = utf8_sub(self.text, 1, pos - 1)  .. utf8_sub(self.text, pos + size); 
end

setmetatable(ustring, {
    __call = function(us, text) 
        return us:new(text);
    end,

    __tostring = function(us)
        return us:tostring() or "";
    end,
});

commonlib.ustring = ustring;
commonlib.utf8_len = utf8_len;
commonlib.utf8_sub = utf8_sub;

function commonlib.split(str, delimiter)
	local result = {};
	if(not str or not delimiter)then 
		return result;
	end
	local line;
	local s = "([^"..delimiter.."]+)";
	for line in string.gmatch(str, s) do
		table.insert(result,line);
	end
	return result;
end

function commonlib.trim(str, ch)
	ch = ch or "%s";
    str = string.gsub(str, "^" .. ch .. "*", "");
    str = string.gsub(str, ch .. "*$", "");
    return str;
end

return {
    ustring = ustring,
};